package cn.com.infcn.spider.scheduler.ftp;

import java.io.IOException;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern;

import org.apache.log4j.Logger;
import org.nlpcn.commons.lang.util.StringUtil;
import org.python.jline.internal.Log;

import cn.com.infcn.spider.URIManager;
import cn.com.infcn.spider.domain.FtpFile;
import cn.com.infcn.spider.domain.FtpJob;
import cn.com.infcn.spider.domain.FtpUriInfo;
import cn.com.infcn.spider.util.FtpConfiguration;
import cn.com.infcn.spider.util.FtpUtil;
import cn.com.infcn.spider.util.MongoDao;
import cn.com.infcn.spider.util.StaticValue;

import com.alibaba.fastjson.JSONObject;

/**
 * 具体的采集类
 * 
 * @author mixl
 *
 */
public class FtpWorker implements Runnable {

	private static final Logger LOG = Logger.getLogger(FtpWorker.class);

	private FtpJob job;

	private FtpUriInfo url;

	private FtpScheduler ftpScheduler;

	private AtomicInteger atomicInteger;

	private Set<Entry<Pattern, Boolean>> makeRegex;

	private MongoDao mongoDao = StaticValue.getBean(MongoDao.class, "mongoDao");
	
	public FtpWorker(FtpScheduler ftpScheduler, FtpJob job, FtpUriInfo url, AtomicInteger atomicInteger) {
		this.job = job;
		this.url = url;
		this.ftpScheduler = ftpScheduler;
		this.atomicInteger = atomicInteger;
		this.makeRegex = makeRegex();
	}

	@Override
	public void run() {
		FtpUtil ftpUtil = new FtpUtil(new FtpConfiguration(url.getServer(), url.getPort(), url.getUser(), url.getPassword(), url.getPath()));
		
		JSONObject result = new JSONObject();
		result.put("_id", url.getUri());
		result.put("update_time", new Date());
		try {
			ftpUtil.connectServer();
			boolean isDirectory = ftpUtil.changeDirectory(url.getPath());
			if(isDirectory){
				List<String> fileList = ftpUtil.getFileList(url.getPath());
				FtpUriInfo urlInfo = null;
				for(String childUrl : fileList){
					urlInfo = new FtpUriInfo(this.url, childUrl);
					URIManager.add(job, urlInfo);
				}
				LOG.debug(String.format("extract %d child path from %s", fileList.size(), url.getPath()));
			} else {
				LOG.debug("start output ftp file :" + url.getUri());
				FtpFile ftpFile = new FtpFile(ftpUtil.getConfig(), url.getPath());
				ftpScheduler.output(ftpFile);
			}
			
			mongoDao.save(cn.com.infcn.spider.URIManager.SUCCESS + job.getName(), result);
		} catch (Exception e) {
			Log.error(e);
			//是否超过预设的异常重试次数
			if(url.getErrCount() >= job.getErrCount()){
				result.put("errCount", url.getErrCount() + 1);
				mongoDao.save(cn.com.infcn.spider.URIManager.ERROR + job.getName(), result);
			} else {
				url.setErrCount(url.getErrCount() + 1);
				URIManager.add(job, url);
			}
			
		} finally {
			atomicInteger.decrementAndGet();
			try {
				ftpUtil.disconnect();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}

	/**
	 * 判断一个网址是否可以忽略
	 * 
	 * @param link
	 * @return
	 */
	private boolean skip(String link) {

		boolean flag = false;

		for (Entry<Pattern, Boolean> entry : makeRegex) {

			if (entry.getValue()) {
				flag = true;
			}

			if (entry.getKey().matcher(link).matches() && entry.getValue()) {
				return false;
			}

			if (entry.getKey().matcher(link).matches() && !entry.getValue()) {
				return true;
			}
		}

		if (flag) {
			return true;
		} else {
			return false;
		}
	}

	private Set<Entry<Pattern, Boolean>> makeRegex() {
		String regexFilter = job.getRegexFilter();
		if (StringUtil.isBlank(regexFilter)) {
			return Collections.emptySet();
		}

		Map<Pattern, Boolean> map = new HashMap<>();

		for (String regex : regexFilter.replace("\r", "").split("\n")) {
			if (StringUtil.isBlank(regex)) {
				continue;
			}
			char f = regex.charAt(0);

			if (f == '-') {
				map.put(Pattern.compile(regex), false);
			} else {
				map.put(Pattern.compile(regex), true);
			}
		}

		return map.entrySet();
	}

}
